package com.atguigu.aiproject.service.impl;

import com.atguigu.aiproject.exception.BusinessException;
import com.atguigu.aiproject.mapper.CreationMapper;
import com.atguigu.aiproject.mapper.UserLikeCreationMapper;
import com.atguigu.aiproject.entity.UserLikeCreation;
import com.atguigu.aiproject.service.CreationLikeService;
import com.atguigu.aiproject.utils.UserContext;
import com.atguigu.aiproject.vo.CreationDetailsVO;
import com.atguigu.aiproject.vo.LikeResultVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import static com.atguigu.aiproject.constant.RedisKeyConstant.*;

@Service
@Slf4j
public class CreationLikeServiceImpl extends ServiceImpl<UserLikeCreationMapper, UserLikeCreation>
        implements CreationLikeService
{
    @Autowired
    private UserLikeCreationMapper userLikeCreationMapper;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private CreationMapper creationMapper;

    /**
     * 获取用户点赞状态
     */
    public boolean getUserLikeStatus(Integer userId, Integer creationId) {
        String userLikedKey = CREATION_LIKED_USERS_KEY + creationId;
        String userCheckedKey = CREATION_USER_CHECKED_KEY + creationId;

        // 1. 查询点赞集合
        Boolean isLiked = redisTemplate.opsForSet().isMember(userLikedKey, userId.toString());
        if (isLiked != null && isLiked) {
            return true;
        }

        // 2. 查询用户检查记录
        Boolean hasChecked = redisTemplate.opsForSet().isMember(userCheckedKey, userId.toString());
        if (hasChecked != null && hasChecked) {
            return false;
        }
        // 3. 查询数据库
        boolean dbLiked = existsByUserIdAndCreationId(userId, creationId);
        // 4. 更新缓存
        if (dbLiked) {
            redisTemplate.opsForSet().add(userLikedKey, userId.toString());
        } else {
            redisTemplate.opsForSet().add(userCheckedKey, userId.toString());
            redisTemplate.expire(userCheckedKey, Duration.ofHours(2));
        }
        return dbLiked;
    }

    /**
     * 设置当前用户点赞状态
     */
    public void setCurrentUserLikeStatus(CreationDetailsVO detail, Integer creationId) {
        try {
            Integer currentUserId = UserContext.getUserId();
            if (currentUserId != null && currentUserId > 0) {
                boolean isLiked = getUserLikeStatus(currentUserId, creationId);
                detail.setIsLiked(isLiked);
            }
        } catch (Exception e) {
            log.error("设置用户点赞状态失败", e);
        }
    }
    /**
     * 点赞/取消点赞
     */
    @Transactional
    public LikeResultVO toggleLike(int creationId) {
        Integer userId = UserContext.getUserId();
        if (userId == null || userId <= 0) {
            throw new BusinessException("请先登录");
        }

        String lockKey = CREATION_LIKE_LOCK_KEY + creationId;
        RLock lock = redissonClient.getLock(lockKey);

        try {
            boolean locked = lock.tryLock(5, 30, TimeUnit.SECONDS);
            if (!locked) {
                throw new BusinessException("操作频繁，请稍后重试");
            }

            try {
                return doToggleLike(creationId, userId);
            } finally {
                lock.unlock();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new BusinessException("点赞操作被中断");
        }
    }

    /**
     * 实际的点赞/取消点赞逻辑
     */
    private LikeResultVO doToggleLike(Integer creationId, Integer userId) {
        String userLikedKey = CREATION_LIKED_USERS_KEY + creationId;
        boolean isLiked = getUserLikeStatus(userId, creationId);

        if (isLiked) {
            return cancelLike(creationId, userId, userLikedKey);
        } else {
            return addLike(creationId, userId, userLikedKey);
        }
    }

    /**
     * 添加点赞
     */
    private LikeResultVO addLike(Integer creationId, Integer userId, String userLikedKey) {
        String detailKey = CREATION_DETAIL_KEY + creationId;
        String userCheckedKey = CREATION_USER_CHECKED_KEY + creationId;

        try {
            // 更新Redis
            redisTemplate.opsForSet().add(userLikedKey, userId.toString());
            redisTemplate.opsForSet().remove(userCheckedKey, userId.toString());
            Long newLikeCount = redisTemplate.opsForHash().increment(detailKey, "liked", 1);

            // 异步更新数据库
            CompletableFuture.runAsync(() -> {
                try {
                    this.save(new UserLikeCreation(userId, creationId, LocalDateTime.now()));
                    creationMapper.incrementLikeCount(creationId);
                } catch (Exception e) {

                    log.error("异步更新数据库失败: creationId={}, userId={}", creationId, userId, e);
                }
            });

            return new LikeResultVO(true, newLikeCount.intValue(), "点赞成功");
        } catch (Exception e) {
            throw new BusinessException("点赞失败，请重试");
        }
    }

    /**
     * 取消点赞
     */
    private LikeResultVO cancelLike(Integer creationId, Integer userId, String userLikedKey) {
        String detailKey = CREATION_DETAIL_KEY + creationId;
        String userCheckedKey = CREATION_USER_CHECKED_KEY + creationId;

        try {
            // 更新Redis
            redisTemplate.opsForSet().remove(userLikedKey, userId.toString());
            redisTemplate.opsForSet().add(userCheckedKey, userId.toString());
            Long newLikeCount = redisTemplate.opsForHash().increment(detailKey, "liked", -1);

            // 异步更新数据库
            CompletableFuture.runAsync(() -> {
                try {
                    deleteUserLike(userId, creationId);
                    creationMapper.decrementLikeCount(creationId);
                } catch (Exception e) {
                    log.error("异步更新数据库失败: creationId={}, userId={}", creationId, userId, e);
                }
            });

            return new LikeResultVO(false, newLikeCount.intValue(), "取消点赞成功");
        } catch (Exception e) {
            throw new BusinessException("取消点赞失败，请重试");
        }
    }


    /**
     * 判断用户是否已经点赞过该创作
     *
     */
    public boolean existsByUserIdAndCreationId(Integer userId, Integer creationId) {
        QueryWrapper<UserLikeCreation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("creation_id", creationId);
        return userLikeCreationMapper.exists(queryWrapper);
    }

    /**
     * 删除用户点赞记录

     */
    @Override
    public void deleteUserLike(Integer userId, Integer creationId) {
        QueryWrapper<UserLikeCreation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("creation_id", creationId);
        userLikeCreationMapper.delete(queryWrapper);
    }

}
